// LemCoop
// Copyright (C) 2013  Oliver Naumann <bldrax@gmail.com>

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#include "sprite.h"

Sprite::Sprite()
{
	m_opacity = 1.0f;
	m_scale = 1.0f;
	m_x = 0;
	m_y = 0;

	m_current_animation = 0;
	m_current_animation_running = false;
	m_in_single_animation = false;

	m_has_graphics = false;
}

Sprite::Sprite(Animation first_animation, bool first_animation_running)
{
	m_animations.push_back(first_animation);

	m_opacity = 1.0f;
	m_scale = 1.0f;
	m_x = 0;
	m_y = 0;

	m_current_animation = 0;
	m_current_animation_running = first_animation_running;
	m_in_single_animation = false;

	m_has_graphics = true;
}

void Sprite::AddAnimation(Animation animation)
{
	m_animations.push_back(animation);
	m_has_graphics = true;
}

bool Sprite::SetCurrentAnimation(unsigned number)
{
	if (m_animations.size() == 0)
	{
		LogManager::LogLine("Error: Sprite tried to set animations but no animations exist.");
		return false;
	}

	if (number >= m_animations.size())
	{
		LogManager::LogLine("Warning: Sprite tried to set animation number " + boost::lexical_cast<std::string>(number)
			+ " but this does not exist. Running animation 0 instead.");
		number = 0;
	}

	m_current_animation = number;
	ResetCurrentAnimation();
	return true;
}

void Sprite::PlayAnimation()
{
	m_current_animation_running = true;
}

void Sprite::StopAnimation()
{
	m_current_animation_running = false;
}

void Sprite::ResetCurrentAnimation()
{
	m_animations.at(m_current_animation).Reset();
}

bool Sprite::PlayAnimationOnce(unsigned number)
{
	if (m_animations.size() == 0)
	{
		LogManager::LogLine("Error: Sprite tried to set animations but no animations exist.");
		return false;
	}

	if (number >= m_animations.size())
	{
		LogManager::LogLine("Warning: Sprite tried to set animation number " + boost::lexical_cast<std::string>(number)
			+ " but this does not exist. Running animation 0 instead.");
		number = 0;
	}

	// If a single animation is already playing, stop it by resetting.
	if (m_in_single_animation)
	{
		m_animations.at(m_single_animation).Reset();
	}

	m_in_single_animation = true;
	m_single_animation = number;
	m_animations.at(m_single_animation).Reset();

	return true;
}

void Sprite::Update(float timing_factor)
{
	if (m_in_single_animation)
	{
		m_animations.at(m_single_animation).Update(timing_factor);

		// If the single animation has ended, reset and go back to main animation.
		if (m_animations.at(m_single_animation).animation_ended())
		{
			m_animations.at(m_single_animation).Reset();
			m_in_single_animation = false;
		}
	}
	else
	{
		if (m_current_animation_running)
		{
			m_animations.at(m_current_animation).Update(timing_factor);
		}
	}
}

void Sprite::Draw()
{
	// TODO: Do some better error handling.
	if (m_has_graphics == false)
		LogManager::LogLine("Warning: Trying to draw a sprite but it seems to have no animations for drawing.");

	// Which animation has to be drawn?
	if (m_in_single_animation)
	{
		m_animations.at(m_single_animation).Draw(m_x, m_y, m_scale, m_scale, m_opacity);
	}
	else
	{
		m_animations.at(m_current_animation).Draw(m_x, m_y, m_scale, m_scale, m_opacity);
	}
}